<!DOCTYPE html>
<html>
<head>
    <meta name="viewport" content="minimum-scale=1.0, width=device-width, maximum-scale=1.0, user-scalable=no"/>
    <meta charset="utf-8">
    <script src="https://unpkg.com/redux@3.7.2/dist/redux.min.js"></script>
    <script src="https://unpkg.com/babel-standalone@6.15.0/babel.min.js"></script>
    <script src="https://unpkg.com/node-uuid@1.4.7/uuid.js"></script>
    <title>Redux</title>
</head>
<body>
<div id="react-container"></div>
  <script type="text/babel">

      const { createStore, combineReducers, compose, applyMiddleware } = Redux
      const { v4 } = uuid

      const color = (state = {}, action) => {
          switch (action.type) {
              case "ADD_COLOR":
                  return {
                      id: action.id,
                      title: action.title,
                      color: action.color,
                      timestamp: action.timestamp,
                      rating: 0
                  }
              case "RATE_COLOR":
                  return (state.id !== action.id) ?
                      state :
                      {
                          ...state,
                          rating: action.rating
                      }
              default :
                  return state
          }
      }

      const colors = (state = [], action) => {
          switch (action.type) {
              case "ADD_COLOR" :
                  return [
                      ...state,
                      color({}, action)
                  ]
              case "RATE_COLOR" :
                  return state.map(
                      c => color(c, action)
                  )
              case "REMOVE_COLOR" :
                  return state.filter(
                      c => c.id !== action.id
                  )
              default:
                  return state
          }
      }

      const sort = (state="SORTED_BY_DATE", action) => {
          switch (action.type) {
              case "SORT_COLORS":
                  return action.sortBy
              default :
                  return state
          }
      }

      const addColor = (title, color) =>
          ({
              type: "ADD_COLOR",
              id: v4(),
              title,
              color,
              timestamp: new Date().toString()
          })

      const removeColor = id =>
          ({
              type: "REMOVE_COLOR",
              id
          })

      const rateColor = (id, rating) =>
          ({
              type: "RATE_COLOR",
              id,
              rating
          })

      const sortColors = sortedBy =>
          (sortedBy === "rating") ?
              ({
                  type: "SORT_COLORS",
                  sortBy: "SORTED_BY_RATING"
              }) :
              (sortedBy === "title") ?
                  ({
                      type: "SORT_COLORS",
                      sortBy: "SORTED_BY_TITLE"
                  }) :
                  ({
                      type: "SORT_COLORS",
                      sortBy: "SORTED_BY_DATE"
                  })




      const logger = store => next => action => {
          let result
          console.groupCollapsed("dispatching", action.type)
          console.log('prev state', store.getState())
          console.log('action', action)
          result = next(action)
          console.log('next state', store.getState())
          console.groupEnd()
          return result
      }

      const saver = store => next => action => {
          let result = next(action)
          localStorage['redux-store'] = JSON.stringify(store.getState())
          return result
      }

      const store = applyMiddleware(logger,saver)(createStore)(
          combineReducers({ colors, sort }),
          (localStorage['redux-store']) ?
              JSON.parse(localStorage['redux-store']) :
              {}
      )



      const populate = compose(
        () => console.log('color coung', store.getState().colors.length),
        () => store.dispatch(addColor("Big Blue", "#0000FF")),
        () => store.dispatch(addColor("Tomato", "#990000")),
        () => store.dispatch(addColor("lawn", "#009900")),
        () => store.dispatch(addColor("Party Pink", "#F142FF"))
      )



      populate()




  </script>
</body>
</html>
